#include "GLES2DefaultHardwareBufferManager.h"

namespace PVM
{
	GLES2DefaultHardwareVertexBuffer::GLES2DefaultHardwareVertexBuffer(size_t vertexSize,
																	   size_t numVertices,
																	   HardwareBuffer::Usage usage)
	: HardwareVertexBuffer(0, vertexSize, numVertices, usage, true, false)
	{
		mpData = static_cast<unsigned char*>(malloc(mSizeInBytes));
	}
	
	GLES2DefaultHardwareVertexBuffer::GLES2DefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr,
																	   size_t vertexSize,
																	   size_t numVertices,
																	   HardwareBuffer::Usage usage)
	: HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, true, false)
	{
		mpData = static_cast<unsigned char*>(malloc(mSizeInBytes));
	}
	
	GLES2DefaultHardwareVertexBuffer::~GLES2DefaultHardwareVertexBuffer()
	{
		free(mpData);
	}
	
	void* GLES2DefaultHardwareVertexBuffer::lockImpl(size_t offset,
													 size_t length,
													 LockOptions options)
	{
		return mpData + offset;
	}
	
	void GLES2DefaultHardwareVertexBuffer::unlockImpl(void)
	{
	}
	
	void* GLES2DefaultHardwareVertexBuffer::lock(size_t offset,
												 size_t length,
												 LockOptions options)
	{
		mIsLocked = true;
		return mpData + offset;
	}
	
	void GLES2DefaultHardwareVertexBuffer::unlock(void)
	{
		mIsLocked = false;
	}
	
	void GLES2DefaultHardwareVertexBuffer::readData(size_t offset,
													size_t length,
													void* pDest)
	{
		assert((offset + length) <= mSizeInBytes);
		memcpy(pDest, mpData + offset, length);
	}
	
	void GLES2DefaultHardwareVertexBuffer::writeData(size_t offset,
													 size_t length,
													 const void* pSource,
													 bool discardWholeBuffer)
	{
		assert((offset + length) <= mSizeInBytes);
		memcpy(mpData + offset, pSource, length);
	}
	
	GLES2DefaultHardwareIndexBuffer::GLES2DefaultHardwareIndexBuffer(IndexType idxType,
																	 size_t numIndexes,
																	 HardwareBuffer::Usage usage)
	: HardwareIndexBuffer(0, idxType, numIndexes, usage, true, false)
	{
		if (idxType == HardwareIndexBuffer::IT_32BIT)
		{
			PVM_EXCEPT("32 bit hardware buffers are not allowed in OpenGL ES.",
					   "GLES2DefaultHardwareIndexBuffer");
		}
		mpData = new unsigned char[mSizeInBytes];
	}
	
	GLES2DefaultHardwareIndexBuffer::~GLES2DefaultHardwareIndexBuffer()
	{
		delete[] mpData;
	}
	
	void* GLES2DefaultHardwareIndexBuffer::lockImpl(size_t offset, size_t length, LockOptions options)
	{
		return mpData + offset;
	}
	
	void GLES2DefaultHardwareIndexBuffer::unlockImpl(void)
	{
	}
	
	void* GLES2DefaultHardwareIndexBuffer::lock(size_t offset, size_t length, LockOptions options)
	{
		mIsLocked = true;
		return mpData + offset;
	}
	
	void GLES2DefaultHardwareIndexBuffer::unlock(void)
	{
		mIsLocked = false;
	}
	
	void GLES2DefaultHardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest)
	{
		assert((offset + length) <= mSizeInBytes);
		memcpy(pDest, mpData + offset, length);
	}
	
	void GLES2DefaultHardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource,
													bool discardWholeBuffer)
	{
		assert((offset + length) <= mSizeInBytes);
		memcpy(mpData + offset, pSource, length);
	}
	
	GLES2DefaultHardwareBufferManagerBase::GLES2DefaultHardwareBufferManagerBase()
	{
	}
	
	GLES2DefaultHardwareBufferManagerBase::~GLES2DefaultHardwareBufferManagerBase()
	{
		destroyAllDeclarations();
		destroyAllBindings();
	}
	
	HardwareVertexBufferSharedPtr
	GLES2DefaultHardwareBufferManagerBase::createVertexBuffer(size_t vertexSize,
															  size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer)
	{
		return HardwareVertexBufferSharedPtr(
		new GLES2DefaultHardwareVertexBuffer(vertexSize, numVerts, usage));
	}
	
	HardwareIndexBufferSharedPtr
	GLES2DefaultHardwareBufferManagerBase::createIndexBuffer(HardwareIndexBuffer::IndexType itype,
															 size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer)
	{
		return HardwareIndexBufferSharedPtr(
		new GLES2DefaultHardwareIndexBuffer(itype, numIndexes, usage));
	}
	
	PVM::RenderToVertexBufferSharedPtr GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer(void)
	{
		PVM_EXCEPT("Cannot create RenderToVertexBuffer in GLES2DefaultHardwareBufferManagerBase",
				   "GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer");
	}
}
